( function() {
	// region 常量
	var element = Z.element;
	var Box = element.Box;
	var Label = element.Label;
	var VLine = element.VLine;
	var Event = Z.Event;
	// endregion

	// region util
	// 断言,用于抛出不可恢复错误
	function assert( flag, msg ) {
		if ( !flag ) throw new Error( msg );
	}

	// 遍历数组
	function loopArray( list, block ) {
		var i, len;
		for ( i = 0, len = list.length; i < len; i++ ) {
			block( list[i], i );
		}
	}

	// 遍历链表
	function loopLinkList( root, func ) {
		var cur;
		for ( cur = root; cur !== null; cur = cur.next ) {
			func( cur );
		}
	};
	// endregion

	// region action系统
	// struct ShortCut { bool ctrl; bool alt; bool shift; int key; }
	// struct Action { void( Platform )? verify; void( Platform ) action; String name; };
	// struct KeyAction { ShortCut shortCut; void( Platform )? verify; void( Platform ) action; }

	// 触发事件
	function trigAction( action, platform ) {
		// 如果没有验证函数,或者函数通过,则执行
		if ( action.verify === undefined || action.verify( platform ) ) {
			action.action( platform );
		}
	}

	// endregion
	// region 键盘系统
	var KeyCode = {
		Backspace : 8,
		Tab : 9,
		Enter : 13,
		Shift : 16,
		Ctrl : 17,
		Alt : 18,
		PauseBreak : 19,
		CapsLock : 20,
		Esc : 27,
		PageUp : 33,
		PageDown : 34,
		End : 35,
		Home : 36,
		LeftArrow : 37,
		UpArrow : 38,
		RigthArrow : 39,
		DownArrow : 40,
		Ins : 45,
		Del : 46,
		Num0 : 48,
		Num1 : 49,
		Num2 : 50,
		Num3 : 51,
		Num4 : 52,
		Num5 : 53,
		Num6 : 54,
		Num7 : 55,
		Num8 : 56,
		Num9 : 57,
		A : 65,
		B : 66,
		C : 67,
		D : 68,
		E : 69,
		F : 70,
		G : 71,
		H : 72,
		I : 73,
		J : 74,
		K : 75,
		L : 76,
		M : 77,
		N : 78,
		O : 79,
		P : 80,
		Q : 81,
		R : 82,
		S : 83,
		T : 84,
		U : 85,
		V : 86,
		W : 87,
		X : 88,
		Y : 89,
		Z : 90,
		WindowsLeft : 91,
		WindowsRight : 92,
		ContextMenu : 93,
		Numpad0 : 96,
		Numpad1 : 97,
		Numpad2 : 98,
		Numpad3 : 99,
		Numpad4 : 100,
		Numpad5 : 101,
		Numpad6 : 102,
		Numpad7 : 103,
		Numpad8 : 104,
		Numpad9 : 105,
		NumpadAsterisk : 106,
		NumpadAdd : 107,
		Sub : 109,
		NumpadDot : 110,
		NumpadSlash : 111,
		F1 : 112,
		F2 : 113,
		F3 : 114,
		F4 : 115,
		F5 : 116,
		F6 : 117,
		F7 : 118,
		F8 : 119,
		F9 : 120,
		F10 : 121,
		F11 : 122,
		F12 : 123,
		NumLock : 144,
		ScrollLock : 145,
		Semicolon : 186,
		Comma : 188,
		Sub : 189,
		Dot : 190,
		Slash : 191,
		GraveAccent : 192,
		Equal : 61,
		LeftBracket : 219,
		Backslash : 220,
		RigthBracket : 221,
		Quote : 222
	};

	// 键码-名称映射表
	var keyNames = Array( 256 );
	keyNames[8] = "Backspace";
	keyNames[9] = "Tab";
	keyNames[13] = "Enter";
	keyNames[16] = "Shift";
	keyNames[17] = "Ctrl";
	keyNames[18] = "Alt";
	keyNames[19] = "Pause/Break";
	keyNames[20] = "CapsLock";
	keyNames[27] = "Esc";
	keyNames[33] = "PageUp";
	keyNames[34] = "PageDown";
	keyNames[35] = "End";
	keyNames[36] = "Home";
	keyNames[37] = "←";
	keyNames[38] = "↑";
	keyNames[39] = "→";
	keyNames[40] = "↓";
	keyNames[45] = "Ins";
	keyNames[46] = "Del";
	keyNames[48] = "0";
	keyNames[49] = "1";
	keyNames[50] = "2";
	keyNames[51] = "3";
	keyNames[52] = "4";
	keyNames[53] = "5";
	keyNames[54] = "6";
	keyNames[55] = "7";
	keyNames[56] = "8";
	keyNames[57] = "9";
	keyNames[65] = "A";
	keyNames[66] = "B";
	keyNames[67] = "C";
	keyNames[68] = "D";
	keyNames[69] = "E";
	keyNames[70] = "F";
	keyNames[71] = "G";
	keyNames[72] = "H";
	keyNames[73] = "I";
	keyNames[74] = "J";
	keyNames[75] = "K";
	keyNames[76] = "L";
	keyNames[77] = "M";
	keyNames[78] = "N";
	keyNames[79] = "O";
	keyNames[80] = "P";
	keyNames[81] = "Q";
	keyNames[82] = "R";
	keyNames[83] = "S";
	keyNames[84] = "T";
	keyNames[85] = "U";
	keyNames[86] = "V";
	keyNames[87] = "W";
	keyNames[88] = "X";
	keyNames[89] = "Y";
	keyNames[90] = "Z";
	keyNames[91] = "Windows";
	keyNames[92] = "Windows";
	keyNames[93] = "ContextMenu";
	keyNames[96] = "Numpad0";
	keyNames[97] = "Numpad1";
	keyNames[98] = "Numpad2";
	keyNames[99] = "Numpad3";
	keyNames[100] = "Numpad4";
	keyNames[101] = "Numpad5";
	keyNames[102] = "Numpad6";
	keyNames[103] = "Numpad7";
	keyNames[104] = "Numpad8";
	keyNames[105] = "Numpad9";
	keyNames[106] = "Numpad*";
	keyNames[107] = "Numpad+";
	keyNames[109] = "-";
	keyNames[110] = "Numpad.";
	keyNames[111] = "Numpad/";
	keyNames[112] = "F1";
	keyNames[113] = "F2";
	keyNames[114] = "F3";
	keyNames[115] = "F4";
	keyNames[116] = "F5";
	keyNames[117] = "F6";
	keyNames[118] = "F7";
	keyNames[119] = "F8";
	keyNames[120] = "F9";
	keyNames[121] = "F10";
	keyNames[122] = "F11";
	keyNames[123] = "F12";
	keyNames[144] = "NumLock";
	keyNames[145] = "ScrollLock";
	keyNames[186] = ";";
	keyNames[188] = ",";
	keyNames[189] = "-";
	keyNames[190] = ".";
	keyNames[191] = "/";
	keyNames[192] = "`";
	keyNames[61] = "=";
	keyNames[219] = "[";
	keyNames[220] = "\\";
	keyNames[221] = "]";
	keyNames[222] = "'";

	// 键的数量
	var KeyNum = ( function() {
		var retVal = 0;
		loopArray( keyNames, function( item ) {
					if ( item !== undefined ) {
						++retVal;
					}
				} );
		return retVal;
	} )();

	// 判断一个键码是否是有效的
	function isKeyValid( keyCode ) {
		return keyCode < 256 && keyNames[keyCode] !== undefined;
	}

	// 返回一个键码的名称
	function keyName( keyCode ) {
		assert( isKeyValid( keyCode ), "Invalid Keycode" );
		return keyNames[keyCode];
	}

	// 判断一个键码是否是数字键
	function isKeyAlpha( keyCode ) {
		return keyCode >= 65 && keyCode <= 90;
	}

	function KeyMap( keyArr ) {
		var keyMap = Array( 256 );

		loopArray( keyMap, function( keyCode ) {
					keyMap[keyCode] = true;
				} );

		return function( keyCode ) {
			return keyMap[keyCode] === true;
		};
	}

	function KeymapSystem( AuxiliaryKey ) {
		var AuxiliaryNum = AuxiliaryKey.length; // 辅助键的数量

		// 判断一个键是不是辅助键
		var isAuxiliaryKey = KeyMap( AuxiliaryKey );
		function isNotAuxiliaryKey( keyCode ) {
			return isKeyValid( keyCode ) && !isAuxiliaryKey( keyCode );
		}

		// 键盘映射,数组,辅助键只有up和down
		// 非辅助键有alt/ctrl/shift,以及up和down
		var keyMap = Array( ( AuxiliaryNum + ( KeyNum - AuxiliaryNum ) << 4 ) << 2 );

		// 初始化,全部设置为null
		loopArray( keyMap, function( item, i ) {
					keyMap[i] = null;
				} );

		keyNumbers = Array( 256 ); // 键序号表,keyCode到键序号的映射
		// 制作键序号表,最前面是辅助键,后面是非辅助键
		loopArray( keyNames, function( keyCode ) {
					var auxiliaryNum = 0, unAuxiliaryNum = AuxiliaryNum;
					if ( isKeyValid( keyCode ) ) {
						if ( isAuxiliaryKey( keyCode ) ) {
							keyNumbers[keyCode] = auxiliaryNum;
							++auxiliaryNum;
						}
						else {
							keyNumbers[keyCode] = unAuxiliaryNum;
							++unAuxiliaryNum;
						}
					}
				} );

		function AuxiliaryMapFunc( factor ) {
			return function( key ) {
				return keyNumbers[key.key] * factor;
			};
		}

		function b2i( val ) {
			return val === true ? 1 : 0;
		}

		function UnAuxiliaryMapFunc( factor ) {
			return function( key ) {
				return ( ( ( keyNumbers[key.key] << 3 ) & ( b2i( key.ctrl ) << 2 ) & ( b2i( key.alt ) << 1 ) & ( b2i( key.shift ) ) ) + AuxiliaryNum ) * factor;
			};
		}

		// 根据因子制作注册函数,因子用于计算数组下标,down的因子是1,up的因子是2
		function Regist( factor ) {
			return function( keyActions ) {
				var nodes = Array(); // 节点数组

				// 遍历按键-动作数组
				loopArray( keyActions, function( keyAction ) {
							var key = keyAction.key;

							// 根据是否是辅助键,计算映射函数,并使用映射函数计算出下标
							var mapper = isAuxiliaryKey( key.key ) ? AuxiliaryMapFunc( factor ) : UnAuxiliaryMapFunc( factor );
							var index = mapper( key );

							// 压栈
							var node = {
								action : keyAction.action,
								verify : keyAction.verify,
								previous : keyMap[index]
							};
							keyMap[index] = node;

							// 保存
							nodes.push( {
										index : index,
										node : node
									} );

							return {
								remove : function() {
									// 移除映射,按顺序弹栈
									loopArray( nodes, function( item ) {
												keyMap[item.index] = item.node.previous;
											} );
								}
							};
						} );
			};
		}

		function Trig( factor ) {
			return function( key, event ) {
				// 根据是否是辅助键,计算映射函数,并使用映射函数计算出下标
				var mapper = isAuxiliaryKey( key.key ) ? AuxiliaryMapFunc( factor ) : UnAuxiliaryMapFunc( factor );
				var index = mapper( key );

				if ( keyMap[index] !== null ) {
					trigAction( keyMap[index] );
				}
			};
		}

		return {
			isAuxiliaryKey : isAuxiliaryKey,
			isNotAuxiliaryKey : isNotAuxiliaryKey,
			AuxiliaryKeyNum : AuxiliaryNum,
			onKeydown : Regist( 1 ),
			onKeyup : Regist( 2 ),
			trigKeydown : Trig( 1 ),
			trigKeyup : Trig( 2 )
		};
	}

	Z.Key = {
		KeyCode : KeyCode,
		isKeyValid : isKeyValid,
		keyName : keyName,
		isKeyAlpha : isKeyAlpha
	};
	// endregion

	// region 菜单系统
	// 菜单类型
	var MenuType = {
		SubMenu : 1,
		Action : 2
	};

	// 制作快捷键字符串
	function shortCutString( shortCut ) {
		var retVal = "";
		if ( shortCut.ctrl ) retVal += "Ctrl+";
		if ( shortCut.alt ) retVal += "Alt+";
		if ( shortCut.shift ) retVal += "Shift+";
		retVal += keyName( shortCut.key );
		return retVal;
	}

	var MinMenuWith = 120; // 菜单最小宽度
	var MenuFont = "13px 微软雅黑";
	function drawMenu( area, menu, zIndex, left, top, Timer, isAccessLabelAccented, actionContext ) {
		var removeAll = null; // 移除所有菜单
		var curFocusMenu = null; // 当前的焦点菜单
		var removeEvent = Event();
		function drawMenuA( menu, parentMenu, zIndex, left, top, countdown ) {
			if ( menu === null ) return;

			var accessMap = Array( 26 ); // 访问表
			var subMenu = null; // 子菜单
			var head = null, tail = null; // 头尾节点
			var curFocusNode = null; // 当前的焦点节点
			var insts = null; // 指令集

			var subArea = area.area( {
						zIndex : zIndex,
						left : left,
						top : top,
						opacity : "0",
						onMouseout : function() {
							// 处理鼠标移除,如果有子菜单,不移除高亮,否则移除高亮并取消焦点
							if ( curFocusNode !== null ) {
								if ( !curFocusNode.hasSubMenu() ) {
									curFocusNode.removeHover();
									curFocusNode = null;
								}
							}
						}
					} );

			// 显示用定时器,倒计时开始时显示,之后有个淡入的效果
			var timer = null, opacity = 0, second = 0;
			timer = Timer( function() {
						if ( countdown > 0 ) {
							--countdown;
						}
						else {
							opacity += second * second;
							second += 0.3;
							if ( opacity < 1 ) {
								subArea.opacity( opacity );
							}
							else {
								subArea.opacity( "1" );
								timer.stop();
							}
						}
					}, 50 );

			var height = 0; // 目前的高度
			var width = MinMenuWith; // 目前的宽度,有最小宽度一说
			var displayAdjusts = Array(); // 显示调整数组,用于摆放完后的尺寸再调整

			// 菜单背景
			var backgroundBox = Box( subArea, {
						background_color : "#F0F0F0",
						border : "thin solid #A0A0A0",
						box_shadow : "2px 2px 0px 0px #8E8E8E"
					} );

			// 遍历菜单,制作菜单项并构成链表
			loopLinkList( menu, function( menuItem ) {
						var curWidth = 32; // 当前宽度
						var thisTop = height + 2;

						function layLabel( text, margin, color ) {
							color = color === undefined ? color : "#FFFFFF";
							curWidth += margin;
							var label = Label( subArea, {
										text : text,
										left : curWidth,
										top : thisTop,
										padding : "2px 0",
										font : MenuFont
									} );
							curWidth += label.offsetWidth();
							return label;
						}

						// 文字内容
						var label = layLabel( menuItem.name, 0 );

						// 高亮矩形
						var hover = null;
						hover = Box( subArea, {
									left : 3,
									top : thisTop,
									zIndex : 1,
									height : label.offsetHeight(),
									opacity : "0",
									background : "cyan",
									border : "thin solid blue",
									border_radius : "2px"
								} );

						var node = null; // 链表节点

						// 显示调整事件
						var displayAdjust = Event();
						displayAdjust.regist( hover.width );

						// 高亮该菜单项
						function hoverThis() {
							// 移除当前选中
							if ( curFocusNode !== null ) {
								curFocusNode.removeHover();
							}
							curFocusNode = node;

							hover.opacity( "0.2" );

							// 移除其他菜单
							if ( subMenu !== null ) {
								subMenu.remove();
								subMenu = null;
							}
						}

						node = {
							hover : hoverThis,
							removeHover : function() {
								hover.opacity( "0" );
							},
							hasSubMenu : function() {
								return menuItem.type === MenuType.SubMenu;
							},
							forward : function() {
							},
							enter : function() {
								removeAll();
							},
							canForward : function() {
								return false;
							},
							next : null,
							previous : tail
						};

						// 处理accessKey
						if ( menuItem.accessKey !== undefined ) {
							var accessKey = menuItem.accessKey;
							assert( isKeyAlpha( accessKey ), "Access key must be alpha key" ); // 确保accessKey是字母键

							layLabel( "(", 2 );
							var accessKeyLabel = layLabel( keyName( accessKey ), 0 );
							if ( isAccessLabelAccented ) accessKeyLabel.text_decoration( "underline" );
							layLabel( ")", 0 );
						}

						if ( menuItem.type === MenuType.SubMenu ) {
							// 绘制子菜单,并置新子菜单为焦点菜单
							function drawSubMenu( countdown ) {
								subMenu = drawMenuA( menuItem.firstChild, insts, zIndex + 1, left + hover.offsetWidth(), top + hover.top() - 2, countdown );
								curFocusMenu = subMenu;
								return subMenu;
							}

							// 有前进动作
							node.forward = function() {
								var subMenuInst = null;
								subMenuInst = drawSubMenu( 0 );
								subMenuInst.next();
							};

							// 回车动作和前进动作一致
							node.enter = node.forward;

							// 可以前进
							node.canForward = function() {
								return true;
							};

							// 悬停高亮并绘制子菜单
							hover.onMouseover( function() {
										// 设置焦点菜单
										hoverThis();
										curFocusMenu = insts;
										drawSubMenu( 4 );
									} );
						}
						else if ( menuItem.type === MenuType.Action ) {
							var action = menuItem.action;
							var verified = true; // 是否通过验证

							// 若有验证函数,则需要通过验证才能工作
							if ( action.verify !== undefined && action.verify( actionContext ) === false ) {
								label.color( "#888888" );
								verified = false;
							}
							else {
								// 回车动作是触发动作
								node.enter = function() {
									// 进入子菜单以及触发动作节点
									menuItem.action.action( actionContext );
									removeAll();
								};

								// 有点击事件
								hover.onClick( node.enter );
							}

							// 若有快捷键,显示快捷键
							if ( action.shortCut !== undefined ) {
								var shortCutLabel = layLabel( shortCutString( action.shortCut ), 40, verified ? "#000000" : "#888888" );

								// 添加宽度调整事件
								displayAdjust.trig( function( width ) {
											shortCutLabel.left( width - shortCutLabel.offsetWidth() - 10 );
										} );
							}

							// 悬停高亮
							hover.onMouseover( function() {
										// 设置焦点菜单
										hoverThis();
										curFocusMenu = insts;
									} );
						}

						// 处理访问事件,访问事件就是回车事件
						if ( menuItem.accessKey !== undefined ) accessMap[menuItem.accessKey - KeyCode.A] = node.enter;

						// 将node插入到列表中
						if ( tail === null ) {
							head = node;
							tail = node;
						}
						else {
							tail.next = node;
							tail = node;
						}

						// 右边再留一些距离
						curWidth += 16;

						displayAdjusts.push( displayAdjust ); // 将宽度设定放入数组中

						// 更新宽度和高度
						if ( curWidth > width ) width = curWidth;
						height += label.offsetHeight();
					} );

			// 循环链表
			tail.next = head;
			head.previous = tail;

			// 重新制作宽高
			backgroundBox.width( width );
			backgroundBox.height( height + 4 );
			subArea.width( backgroundBox.offsetWidth() + 2 );
			subArea.height( backgroundBox.offsetHeight() + 2 );

			// 调整每项的宽度
			loopArray( displayAdjusts, function( event ) {
						event.trig( width - 6 );
					} );

			// 中间那道竖线,一灰一白
			VLine( subArea, {
						left : 24,
						top : 3,
						length : height,
						width : 1,
						style : "solid",
						color : "#E2E3E3"
					} );
			VLine( subArea, {
						left : 25,
						top : 3,
						length : height,
						width : 1,
						style : "solid",
						color : "#FFFFFF"
					} );

			timer.start(); // 开始计时器,开始渐入动画
			function remove() {
				subArea.remove();
				timer.stop();
				if ( subMenu !== null ) {
					subMenu.remove();
				}
				if ( parentMenu !== null ) parentMenu.removeSubMenu();
			}

			insts = {
				remove : remove,
				removeSubMenu : function() {
					subMenu = null;
				},
				access : function( key ) {
					// 访问,如果有访问项,调用它
					if ( accessMap[key] !== undefined ) {
						accessMap[key]();
					}
				},
				enter : function() {
					if ( curFocusNode !== null ) {
						curFocusNode.enter();
					}
				},
				forward : function() {
					if ( curFocusNode !== null ) {
						curFocusNode.forward();
					}
				},
				backward : function() {
					// 如果有父菜单,将焦点交回到父菜单,并移除自己
					if ( parentMenu !== null ) {
						curFocusMenu = parentMenu;
						remove();
					}
				},
				canBackward : function() {
					return parentMenu !== null;
				},
				canForward : function() {
					return curFocusNode !== null ? curFocusNode.canForward() : false;
				},
				next : function() {
					if ( curFocusNode === null ) {
						if ( head !== null ) head.hover();
					}
					else {
						curFocusNode.next.hover();
					}
				},
				previous : function() {
					if ( curFocusNode === null ) {
						if ( tail !== null ) tail.hover();
					}
					else {
						curFocusNode.previous.hover();
					}
				},
				isFocus : function() {
					return curFocusNode === null;
				}
			};

			return insts;
		}
		var menuInsts = drawMenuA( menu, null, zIndex, left, top, 0 );

		// 设置当前焦点
		curFocusMenu = menuInsts;

		// 移除全部
		removeAll = function() {
			menuInsts.remove();
			removeEvent.trig();
		};

		return {
			remove : removeAll,
			access : function( key ) {
				curFocusMenu.access( key );
			},
			enter : function() {
				curFocusMenu.enter();
			},
			forward : function() {
				curFocusMenu.forward();
			},
			backward : function() {
				curFocusMenu.backward();
			},
			canForward : function() {
				return curFocusMenu.isFocus() ? false : curFocusMenu.canForward();
			},
			canBackward : function() {
				return curFocusMenu.isFocus() ? false : curFocusMenu.canBackward();
			},
			next : function() {
				curFocusMenu.next();
			},
			previous : function() {
				curFocusMenu.previous();
			},
			isFocus : function() {
				return curFocusMenu.isFocus();
			},
			onRemove : removeEvent.regist
		};
	}

	// 绘制横幅菜单
	function drawBannerMenu( parentArea, zIndex, left, top, menu, Timer, actionContext ) {
		var onRemove = Event();

		// 创建区域
		var area = parentArea.area( {
					left : left,
					top : top
				} );

		var offsetHeight = area.offsetHeight;

		var curFocus = null; // 当前焦点
		var curMenu = null; // 当前弹出的菜单
		var curNode = null; // 当前节点

		var offset = 0; // 当前偏移,指目前label摆到了哪里
		var height = 0; // 高度

		var head = null, tail = null; // 链表的首和尾

		// 重点标记
		var isAccessLabelAccented = false; // 当该位置位时,所有新绘制的菜单access label都将被强调
		var accessLabelDecorations = Array();
		var accessMap = Array( 26 ); // 访问表

		// 着重显示所有的access label
		function accentAccessLabel( val ) {
			isAccessLabelAccented = val;
			var decoration = val === true ? "underline" : "none";
			loopArray( accessLabelDecorations, function( setDecoration ) {
						setDecoration( decoration );
					} );
		}

		// 失去所有焦点
		function unfocusAll() {
			if ( curMenu !== null ) {
				curMenu.remove();
			}
			else {
				if ( curFocus !== null ) {
					curFocus.unfocus();
					curFocus = null;
				}
			}
			curNode = null;
			onRemove.trig();
		}

		// 背景条
		var backgroundBar = Box( area, {
					background_color : "#F5F5F5",
					border_top : "thin solid #D4D4D4",
					border_bottom : "thin solid #D4D4D4",
					onMousedown : function() {
						unfocusAll();
					}
				} );

		loopArray( menu, function( menuItem ) {
			var startOffset = offset; // 起始偏移

			function layLabel( text, margin ) {
				offset += margin;

				var label = Label( area, {
							top : 1,
							left : offset,
							text : text,
							font : MenuFont
						} );

				offset += label.offsetWidth();

				return label;
			};
			var menuName = layLabel( menuItem.name, 5 );
			height = menuName.offsetHeight();

			// 处理accessKey
			if ( menuItem.accessKey !== undefined ) {
				var accessKey = menuItem.accessKey;
				assert( isKeyAlpha( accessKey ), "Access key must be alpha key" ); // 确保accessKey是字母键

				// 添加label
				layLabel( "(", 2 );
				var accessLabel = layLabel( keyName( accessKey ), 0 );
				accessLabelDecorations.push( accessLabel.text_decoration );
				layLabel( ")", 0 );
			}

			// 右余量
			offset += 5;

			var hover = null;
			var node = null;

			// 聚焦当前菜单
			function focusThis() {
				if ( curFocus !== null ) {
					curFocus.unfocus();
				}

				hover.background_color( "#404040" );
				hover.opacity( "0.3" );

				// 置自己为焦点
				curFocus = {
					unfocus : function() {
						hover.opacity( "0" );
					}
				};

				curNode = node;
			}

			// 绘制当前菜单
			function drawThisMenu() {
				// 移出先前的菜单
				if ( curMenu !== null ) {
					curMenu.remove();
				}

				// 聚焦
				focusThis();

				// 绘制新的菜单
				var myMenu = drawMenu( parentArea, menuItem.menu, zIndex, left + startOffset, offsetHeight() - 2, Timer, isAccessLabelAccented, actionContext );

				myMenu.onRemove( function() {
							curMenu = null;
							if ( curFocus !== null ) {
								curFocus.unfocus();
								curFocus = null;
							}
							curNode = null;

							// 取消对access label的强调
							accentAccessLabel( false );
						} );
				curMenu = myMenu;
			}

			// 如果有accessKey,填充访问表
			if ( menuItem.accessKey !== undefined ) accessMap[menuItem.accessKey] = drawThisMenu;

			// 结成链表
			node = {
				focus : focusThis,
				drawMenu : drawThisMenu,
				next : null,
				previous : tail
			};

			if ( tail === null ) {
				head = node;
				tail = node;
			}
			else {
				tail.next = node;
				tail = node;
			}

			hover = Box( area, {
						left : startOffset,
						width : offset - startOffset,
						height : height,
						border : "thin solid",
						border_radius : "3px",
						opacity : "0",
						onMouseover : function() {
							// 没有得到焦点,仅仅高亮
							if ( curFocus === null ) {
								hover.background_color( "#FFFFFF" );
								hover.opacity( "0.2" );
							}
							else if ( curMenu === null ) {
								// 如果目前没有绘制的菜单,仅获得焦点
								focusThis();
							}
							else {
								// 否则绘制菜单
								drawThisMenu();
							}
						},
						onMouseout : function() {
							if ( curFocus === null ) {
								hover.opacity( "0" );
							}
						},
						onMousedown : function() {
							if ( curMenu !== null ) {
								unfocusAll();
							}
							else {
								drawThisMenu();
							}
						}
					} );

			offset += 3;
		} );

		// 循环链表
		head.previous = tail;
		tail.next = head;

		// 设置高度
		area.height( height + 4 );
		backgroundBar.height( height + 2 );

		function ForBack( np, fw, cfw ) {
			return function() {
				if ( curFocus !== null ) {
					if ( curMenu === null ) {
						curNode[np].focus();
					}
					else if ( curMenu[cfw]() ) {
						curMenu[fw]();
					}
					else {
						curNode[np].drawMenu();
						curMenu.next();
					}
				}
			};
		}

		function UD( np ) {
			return function() {
				if ( curFocus !== null ) {
					if ( curMenu === null ) {
						// 如果没有菜单,绘制菜单
						curNode.drawMenu();
						curMenu.next();
					}
					else {
						curMenu[np]();
					}
				}
			};
		}

		return {
			width : function( val ) {
				area.width( val );
				backgroundBar.width( val );
			},
			focus : function() {
				// 菜单获得焦点,即当菜单为获得焦点时,另菜单的第一项获得焦点
				if ( curFocus === null ) {
					head.focus();
				}
			},
			forward : ForBack( "next", "forward", "canForward" ),
			backward : ForBack( "previous", "backward", "canBackward" ),
			enter : function() {
				if ( curFocus !== null ) {
					if ( curMenu !== null ) {
						// 如果有菜单,并且菜单有焦点,交给菜单进行处理
						if ( curMenu.isFocus() ) {
							curMenu.enter();
						}
						// 否则移出全部焦点
						else {
							unfocusAll();
						}
					}
					else {
						// 如果没有菜单,绘制菜单
						curNode.drawMenu();
						curMenu.next();
					}
				}
			},
			escape : function() {
				if ( curMenu !== null ) {
					var node = curNode;
					// 如果有菜单,移出菜单,但不移出焦点
					curMenu.remove();
					curMenu = null;
					node.focus();
				}
				else if ( curFocus !== null ) {
					// 如果没菜单,但有焦点,移出焦点
					unfocusAll();
				}
			},
			up : UD( "previous" ),
			down : UD( "next" ),
			unfocus : unfocusAll,
			onRemove : onRemove.regist,
			accentAccessLabel : accentAccessLabel,
			access : function( key ) {
				// 如果没有菜单,绘制菜单
				if ( curMenu === null ) {
					if ( accessMap[key] !== undefined ) accessMap[key]();
				}
				else {
					curMenu.access( key );
				}
			}
		};
	}

	Z.Menu = {
		drawMenu : function( arg ) {
			return drawMenu( arg.area, arg.menu, arg.zIndex, arg.left, arg.top, arg.timer, arg.isAccessLabelAccented || false, arg.actionContext );
		},
		drawBannerMenu : function( arg ) {
			return drawBannerMenu( arg.area, arg.zIndex, arg.left, arg.top, arg.menu, arg.timer, arg.actionContext );
		},
		MenuHeight : 23
	};
	// endregion
} )();